/*
 * Copyright (c) 2025 EasyAdmin
 * All rights reserved.
 *
 * This file is part of the [EasAdmin] project.
 * Unauthorized copying of this file, via any medium, is strictly prohibited.
 * Proprietary and confidential.
 *
 * Author: EasyAdmin ( 1073602@qq.com )
 * Website: https://www.xhxiao.com
 */
package com.easy.module.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easy.framework.common.utils.Func;
import com.easy.module.system.cache.DeptCache;
import com.easy.module.system.cache.UserCache;
import com.easy.module.system.entity.SysAppMenuAuth;
import com.easy.module.system.entity.SysDept;
import com.easy.module.system.entity.SysRole;
import com.easy.module.system.entity.SysUser;
import com.easy.module.system.enums.AppMenuAuthTypeEnum;
import com.easy.module.system.mapper.SysAppMenuAuthMapper;
import com.easy.module.system.query.SysAppMenuAuthQuery;
import com.easy.module.system.service.ISysAppMenuAuthService;
import com.easy.module.system.service.ISysRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 应用菜单授权 Service业务
 *
 * @author EasyAdmin ( 1073602@qq.com )
 * @date 2025-08-20
 */
@RequiredArgsConstructor
@Service
public class SysAppMenuAuthServiceImpl extends ServiceImpl<SysAppMenuAuthMapper, SysAppMenuAuth> implements ISysAppMenuAuthService {

    final ISysRoleService sysRoleService;

    @Override
    public List<SysAppMenuAuth> listMenuAuth(SysAppMenuAuthQuery query) {
        List<SysAppMenuAuth> list = list(query);
        if (Func.isNotEmpty(list)) {
            List<Long> roleIdList = list.stream().filter(p -> AppMenuAuthTypeEnum.ROLE.getValue().equals(p.getAuthType()))
                    .map(SysAppMenuAuth::getAuthId).distinct().collect(Collectors.toList());
            Map<Long, String> roleNameMap = null;
            if (Func.isNotEmpty(roleIdList)) {
                roleNameMap = Optional.of(sysRoleService.list(Wrappers.<SysRole>lambdaQuery().in(SysRole::getId, roleIdList)))
                        .orElse(new ArrayList<>()).stream().collect(Collectors.toMap(SysRole::getId, role -> role.getRoleName()));
            }
            for (SysAppMenuAuth item : list) {
                item.setAuthTypeDesc(AppMenuAuthTypeEnum.getName(item.getAuthType()));
                if (AppMenuAuthTypeEnum.DEPT.getValue().equals(item.getAuthType())) {
                    item.setAuthDesc(DeptCache.get(item.getAuthId()).map(SysDept::getDeptName).orElse(""));
                } else if (AppMenuAuthTypeEnum.ROLE.getValue().equals(item.getAuthType())
                        && null != roleNameMap && roleNameMap.containsKey(item.getAuthId())) {
                    item.setAuthDesc(roleNameMap.get(item.getAuthId()));
                } else if (AppMenuAuthTypeEnum.USER.getValue().equals(item.getAuthType())) {
                    item.setAuthDesc(Optional.of(UserCache.get(item.getAuthId())).map(SysUser::getNickname).orElse(""));
                }
                item.setCreatedByDesc(Optional.of(UserCache.get(item.getCreatedBy())).map(SysUser::getNickname).orElse(""));
            }
        }
        return list;
    }

    @Override
    public Boolean auth(SysAppMenuAuth model) {
        List<SysAppMenuAuth> appMenuAuthList = new ArrayList<>();
        for (Long menuId : model.getMenuIdList()) {
            if (count(Wrappers.<SysAppMenuAuth>lambdaQuery()
                    .eq(SysAppMenuAuth::getAuthType, model.getAuthType())
                    .eq(SysAppMenuAuth::getAuthId, model.getAuthId())
                    .eq(SysAppMenuAuth::getMenuId, menuId)) > 0) {
                throw new IllegalArgumentException("授权类型的对象已经授权！");
            }
            SysAppMenuAuth appMenuAuth = new SysAppMenuAuth();
            appMenuAuth.setAuthId(model.getAuthId());
            appMenuAuth.setMenuId(menuId);
            appMenuAuth.setAuthType(model.getAuthType());
            appMenuAuthList.add(appMenuAuth);
        }
        if (appMenuAuthList.size() > 0) {
            return saveBatch(appMenuAuthList);
        }
        return false;
    }

    @Override
    public Boolean cancelAuth(List<Long> idList) {
        if (Func.isNotEmpty(idList)) {
            return removeBatchByIds(idList);
        }
        return true;
    }

    @Override
    public List<Long> getMenuIdListByOrgId(Long orgId, List<Long> roleIdList, Long userId) {
        List<Long> menuIdList = new ArrayList<>();
        List<Long> authIdList = new ArrayList<>();
        if (null != orgId) {
            authIdList.add(orgId);
        }
        if (Func.isNotEmpty(roleIdList)) {
            authIdList.addAll(roleIdList);
        }
        if (null != userId) {
            authIdList.add(userId);
        }
        if (Func.isNotEmpty(authIdList)) {
            List<SysAppMenuAuth> list = list(Wrappers.<SysAppMenuAuth>lambdaQuery().in(SysAppMenuAuth::getAuthId, authIdList));
            if (Func.isNotEmpty(list)) {
                if (null != orgId) {
                    menuIdList.addAll(list.stream().filter(p -> orgId.equals(p.getAuthId()) && AppMenuAuthTypeEnum.DEPT.getValue().equals(p.getAuthType())).map(SysAppMenuAuth::getMenuId).collect(Collectors.toList()));
                }
                if (Func.isNotEmpty(roleIdList)) {
                    menuIdList.addAll(list.stream().filter(p -> roleIdList.contains(p.getAuthId()) && AppMenuAuthTypeEnum.ROLE.getValue().equals(p.getAuthType())).map(SysAppMenuAuth::getMenuId).collect(Collectors.toList()));
                }
                if (null != userId) {
                    menuIdList.addAll(list.stream().filter(p -> userId.equals(p.getAuthId()) && AppMenuAuthTypeEnum.USER.getValue().equals(p.getAuthType())).map(SysAppMenuAuth::getMenuId).collect(Collectors.toList()));
                }
            }
        }
        return menuIdList.stream().distinct().collect(Collectors.toList());
    }
}